package com.sq.util.web;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sq.util.JsonUtil;
import com.sq.util.StringUtil;

public class IpUtil {
    private static Logger log = LoggerFactory.getLogger(IpUtil.class);

    /**
     * 做安全验证,需要配置nginx的proxy_set_header X-Real-IP $remote_addr;
     */
    public static String getRealIp(HttpServletRequest request) {
        return StringUtil.trim(request.getHeader("X-Real-IP"));
    }

    /**
     * 做日志记录的,获取用户原始ip,这个可以伪造的
     */
    /**
     * 做日志记录的,获取用户原始ip,这个可以伪造的
     */
    public static String getLogIp(HttpServletRequest request) {
        String realIp = getRealIp(request);
        if (StringUtil.isNotBlank(realIp)) {
            return realIp;
        }
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtil.isBlank(ip)) {
            return request.getRemoteAddr();
        }
        int index = ip.indexOf(',');
        String clientIp = ip;
        if (index > 0) {
            clientIp = ip.substring(0, index).trim();
        }
        if ("127.0.0.1".equals(clientIp) || !isLicitIp(clientIp)) {
            return request.getRemoteAddr();
        }
        return clientIp;
    }

    public static String getIp(String hostName) {
        try {
            InetAddress address = InetAddress.getByName(hostName);
            return address.getHostAddress().toString();
        } catch (Exception e) {
            return "";
        }
    }

    public static Set<String> listIpsByHost(String hostName) throws UnknownHostException {
        if (StringUtil.isBlank(hostName)) {
            return Collections.emptySet();
        }
        Set<String> ips = new HashSet<String>();
        InetAddress[] array = InetAddress.getAllByName(hostName);
        // 遍历获取的域名所有的IP
        for (int i = 0; i < array.length; i++) {
            String host = array[i].getHostAddress();
            ips.add(host);
        }
        return ips;
    }

    public static Set<String> listLocalIps() {
        Enumeration<NetworkInterface> allNetInterfaces = null;
        try {
            allNetInterfaces = NetworkInterface.getNetworkInterfaces();
        } catch (SocketException e) {
            e.printStackTrace();
            return Collections.emptySet();
        }
        InetAddress inetAddress = null;
        Set<String> ips = new HashSet<String>();
        while (allNetInterfaces.hasMoreElements()) {
            NetworkInterface netInterface = allNetInterfaces.nextElement();
            Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
            while (addresses.hasMoreElements()) {
                inetAddress = addresses.nextElement();
                if (inetAddress != null && inetAddress instanceof Inet4Address) {
                    String ip = inetAddress.getHostAddress();
                    if ("127.0.0.1".equals(StringUtil.trim(ip))) {
                        continue;
                    }
                    if ("localhost".equals(inetAddress.getHostName())) {
                        continue;
                    }
                    ips.add(ip);
                }
            }
        }
        try {
            String result = HttpGetUtil.execute("http://isp.duowan.com/");
            int start = result.indexOf("data=") + 5;
            int end = result.lastIndexOf("}") + 1;
            if (start < end) {
                result = result.substring(start, end);
                String s = (String) JsonUtil.toMap(result).get("ip");
                if (StringUtil.isNotBlank(s)) {
                    ips.add(s);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return ips;
    }

    public static String getLocalIp() {
        Enumeration<NetworkInterface> allNetInterfaces = null;
        try {
            allNetInterfaces = NetworkInterface.getNetworkInterfaces();
        } catch (SocketException e) {
            return "";
        }
        InetAddress inetAddress = null;
        String result = "";
        while (allNetInterfaces.hasMoreElements()) {
            NetworkInterface netInterface = allNetInterfaces.nextElement();
            Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
            while (addresses.hasMoreElements()) {
                inetAddress = addresses.nextElement();
                if (inetAddress == null) {
                    continue;
                }
                if (!(inetAddress instanceof Inet4Address)) {
                    continue;
                }
                String ip = StringUtil.trim(inetAddress.getHostAddress());
                if ("127.0.0.1".equals(ip)) {
                    continue;
                }
                if ("localhost".equals(inetAddress.getHostName())) {
                    continue;
                }
                String name = StringUtil.trim(netInterface.getName());
                if (name.startsWith("eth") || name.startsWith("en")) {
                    return ip;
                }
                result = ip;
            }
        }
        return result;
    }

    private static final java.util.regex.Pattern IS_LICIT_IP_PATTERN = java.util.regex.Pattern
            .compile("^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$");

    private static boolean isLicitIp(final String ip) {
        if (StringUtil.isBlank(ip)) {
            return false;
        }
        Matcher m = IS_LICIT_IP_PATTERN.matcher(ip);
        if (!m.find()) {
            return false;
        }
        return true;
    }
}
